package cn.stylefeng.guns.modular.yingbao.handler;
import	java.util.stream.Stream;
import java.util.*;

import cn.stylefeng.guns.modular.yingbao.entity.*;
import cn.stylefeng.guns.modular.yingbao.service.*;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.stream.Collectors;

import static java.util.stream.Collectors.toConcurrentMap;
import static java.util.stream.Collectors.toList;

/**
 * @author jj
 * @date 2019/12/19 15:49
 */
@Slf4j
@Service
public class GroupHandler {

    @Autowired
    SysUserGroupService sysUserGroupService;

    @Autowired
    SysGroupSettingService sysGroupSettingService;

    @Autowired
    SysGroupLogService sysGroupLogService;

    @Autowired
    SysBuildingService sysBuildingService;

    @Autowired
    UserMoneyService userMoneyService;

    @Transactional(rollbackFor = Exception.class,timeout = 360)
    public synchronized void groupHandler(SysBuilding sysBuilding){
        //获取上级
        List<String> ids = sysUserGroupService.findDescId(String.valueOf(sysBuilding.getUserid()));
        //获取每个级别属性
        List<SysGroupSetting>  settingList = sysGroupSettingService.list(null);
        //获取建仓userid
        Long buid = sysBuilding.getUserid();
        //获取建仓时间
        Date createTime = sysBuilding.getCreateTime();
        for (int i=0;i<ids.size();i++){
            //获取上级得userid
            Long userid = Long.valueOf(ids.get(i));
            //判断上级是否创建仓位
            SysBuilding sysBuilding1 = sysBuildingService.getOne(new QueryWrapper<SysBuilding>().eq("userid", userid)
                    .eq("stuats","1"));
            if (sysBuilding1==null){
                log.error("没有持有相应等级的建仓合约，无法返利");
                continue;
            }
            //判断是否在建仓之后建得
            if (sysBuilding1.getCreateTime().after(createTime)){
                log.error("在建仓之后建的仓");
                continue;
            }
            //上级团队单增加
            SysUserGroup sysUserGroup = sysUserGroupService.getOne(new QueryWrapper<SysUserGroup>().eq("userid", userid));
            sysUserGroup.setGroupOrdinalSize(sysUserGroup.getGroupOrdinalSize()+1);
            //添加到团队建仓组里面
            String teamId = sysUserGroup.getTeamId();
            List<String> arrayList;
            if (StringUtils.isNotEmpty(teamId)){
                arrayList= JSONObject.parseObject(teamId, List.class);
                if (!arrayList.contains(String.valueOf(buid))){
                    arrayList.add(String.valueOf(buid));
                }else {
                    sysUserGroup.setGroupOrdinalSize(sysUserGroup.getGroupOrdinalSize()-1);

                }
            }else {
                arrayList=new ArrayList<>();
                arrayList.add(String.valueOf(buid));
            }

            //判断等级是否升级
            Long groupOrdinalSize = sysUserGroup.getGroupOrdinalSize();
            List<SysGroupSetting> collect = settingList.stream().filter(sysGroupSetting ->
                    sysGroupSetting.getMaxiMum() >= groupOrdinalSize && sysGroupSetting.getMiniMum() <= groupOrdinalSize).collect(toList());
            if (collect.size()>0){
                log.error("等级升级");
                SysGroupSetting sysGroupSetting = collect.get(0);
                sysUserGroup.setGrade(sysGroupSetting.getGrade());
            }

            //持久化数据
            String jsonString = JSONObject.toJSONString(arrayList);
            sysUserGroup.setTeamId(jsonString);
            int version=sysUserGroup.getVersion();
            sysUserGroup.setVersion(version+1);
            boolean update = sysUserGroupService.update(sysUserGroup, new QueryWrapper<SysUserGroup>().eq("id", sysUserGroup.getId()).eq("version", version));
            if (!update){
                log.error ("sysUserGroup建仓更新错误");
            }
            //createTime=sysBuilding1.getCreateTime();
        }
    }


    public synchronized void resultHandler(SysBuilding sysBuilding){
        //完成建仓
        sysBuilding.setStuats("2");
        sysBuilding.setMoney(sysBuilding.getPrice()*sysBuilding.getEarnings()/100);
        sysBuilding.setBuildingTime(new Date());
        int version5 = sysBuilding.getVersion();
        sysBuildingService.update(sysBuilding,new QueryWrapper<SysBuilding>().eq("id",sysBuilding.getId()).eq("version",version5));
        //获取完成建仓的团队数据
        SysUserGroup sysUserGroup = sysUserGroupService.getOne(new QueryWrapper<SysUserGroup>().eq("userid", sysBuilding.getUserid()));
        UserMoney userMoney = userMoneyService.getOne(new QueryWrapper<UserMoney>().eq("userid", sysBuilding.getUserid()));
        //所有下级
        List<String> ascUserids= sysUserGroupService.findAscId(sysBuilding.getUserid());
        //如果团队等级大于1的时候,并且建仓单小于中级单将不返利
        if (sysUserGroup!=null&&sysUserGroup.getGrade()>1&&sysBuilding.getType()==1){
            return;
        }
        //获取相应等级
        SysGroupSetting sysSetting = sysGroupSettingService.getOne(new QueryWrapper<SysGroupSetting>().eq("grade", sysUserGroup.getGrade()));

        if (sysUserGroup==null||sysUserGroup.getGrade()<1){
            return;
        }

        String teamId = sysUserGroup.getTeamId();

        if (StringUtils.isEmpty(teamId)){
            return;
        }
        List<String> arrayList = JSONObject.parseObject(teamId, ArrayList.class);
        if (arrayList==null){
            return;
        }
        //查询同等等级的人,并移除这个下级一下的所有人
        List<SysUserGroup> sysUserGroups = sysUserGroupService.list(new QueryWrapper<SysUserGroup>().in("userid", arrayList).eq("grade",sysUserGroup.getGrade()));

        if (sysUserGroups.size()>0){
            for (SysUserGroup sysUserGroup1:sysUserGroups){

                List<String> ascId = sysUserGroupService.findAscId(sysUserGroup1.getUserid());
                if (ascId.size()>0){
                    for (int i=0;i<ascId.size();i++){
                        String s = ascId.get(i);
                        if (arrayList.contains(s)){
                            arrayList.remove(s);
                        }
                    }
                }
                if (arrayList.contains(String.valueOf(sysUserGroup1.getUserid()))) {
                    arrayList.remove(String.valueOf(sysUserGroup1.getUserid()));
                }
            }
        }

        //如果等级够的话,只有自己,结算自己建仓单进行返利
        if (arrayList==null||arrayList.size()<1){
            Long shouyi=sysBuilding.getPrice()*sysBuilding.getEarnings()*sysSetting.getEarnings()/10000;
            SysGroupLog sysGroupLog=new SysGroupLog();
            sysGroupLog.setType(sysBuilding.getType());
            sysGroupLog.setOrdinal(sysBuilding.getOrdinal());
            sysGroupLog.setUserid(userMoney.getUserid());
            sysGroupLog.setMoney(shouyi);
            sysGroupLog.setGrade(sysSetting.getGrade());
            sysGroupLog.setCreateTime(new Date());
            sysGroupLogService.save(sysGroupLog);

            sysUserGroup.setMoney(sysUserGroup.getMoney()+shouyi);
            userMoney.setExpandMoney(userMoney.getExpandMoney()+shouyi);
            long version = userMoney.getVersion();
            userMoney.setVersion(version+1);
            userMoneyService.update(userMoney,new QueryWrapper<UserMoney>().eq("id",userMoney.getId()).eq("version",version));

            int version1=sysUserGroup.getVersion();
            sysUserGroup.setVersion(version1+1);
            sysUserGroupService.update(sysUserGroup,new QueryWrapper<SysUserGroup>().eq("id",sysUserGroup.getId()).eq("version",version1));
            return;
        }

        //查找第一层下级userid
        List<SysUserGroup> sysUserGroupList = sysUserGroupService.list(new QueryWrapper<SysUserGroup>().eq("referrer_id", sysBuilding.getUserid()));
        List<String> uids=new ArrayList();
        sysUserGroupList.forEach(sys ->{
            uids.add(String.valueOf(sys.getUserid()));
        });
        //查询出所有的设置条件
        List<SysGroupSetting>  settingList = sysGroupSettingService.list(null);
        //
        for (int i=0;i<arrayList.size();i++){
            //最高等级
            int grade = 0;
            //查询出需要返利的下级单个id
            String userid= arrayList.get(i);
            //根据id查出相关团队
            SysUserGroup sysUserGroupServiceOne = sysUserGroupService.getOne(new QueryWrapper<SysUserGroup>().eq("userid",Long.valueOf(userid) ));
            Long shouyi=0L;
            SysBuilding one;
            if (uids.contains(userid)){

                //添加等级
                grade=sysUserGroupServiceOne.getGrade();
                one = sysBuildingService.getOne(new QueryWrapper<SysBuilding>().eq("userid", Long.valueOf(userid) )
                        .gt("create_time",sysBuilding.getCreateTime())
                        .orderByAsc("create_time").last("limit 1"));

                if (one==null){
                    continue;
                }
                List<SysGroupLog> list = sysGroupLogService.list (new QueryWrapper<SysGroupLog> ()
                        .eq ( "ordinal",one.getOrdinal ()).in("userid",ascUserids));

                int gt=0;
                if (list.size ()>0){
                    Optional<SysGroupLog> max = list.stream().max(Comparator.comparingInt(SysGroupLog::getGrade));
                    SysGroupLog sysGroupLog = max.get();
                    gt= sysGroupLog.getGrade();
                }

                if (gt>=grade){
                    grade=gt;
                }
                if (grade>=sysUserGroup.getGrade ()){
                    continue;
                }

                int gi=grade;
                List<SysGroupSetting> collect = settingList.stream().filter(sysGroupSetting ->
                        sysGroupSetting.getGrade().equals(gi)).collect(toList());
                int earnings=sysSetting.getEarnings();


                if (collect!=null&&collect.size()>0){
                    earnings=earnings-collect.get(0).getEarnings();
                }

                shouyi=one.getPrice()*one.getEarnings()*earnings/10000;


            }else {

                int earnings=sysSetting.getEarnings();
                List<String> descId = sysUserGroupService.findDescId(userid);

                if (descId==null||arrayList==null){
                    continue;
                }
                //交集
                List<String> collect2 =descId.stream().filter(num -> ascUserids.contains(num))
                        .collect(toList());

                //判断等级并且
                if (collect2.size()>0){
                    List<SysBuilding> list = sysBuildingService.list(new QueryWrapper<SysBuilding>().in("userid", collect2)
                            .eq("stuats", "1"));
                        if (list.size()>0){
                            List<Long> useridList=new ArrayList();
                        list.forEach(sys ->{
                            useridList.add(sys.getUserid());
                        });

                        List<SysUserGroup> list1 = sysUserGroupService.list(new QueryWrapper<SysUserGroup>().in("userid", useridList));
                        Optional<SysUserGroup> max = list1.stream().max(Comparator.comparingInt(SysUserGroup::getGrade));
                        SysUserGroup sysUserGroup1 = max.get();
                        grade= sysUserGroup1.getGrade();
                    }else {
                        grade=sysUserGroupServiceOne.getGrade();
                    }
                }else {
                    grade=sysUserGroupServiceOne.getGrade();
                }



                one = sysBuildingService.getOne(new QueryWrapper<SysBuilding>().eq("userid", userid)
                        .gt("create_time",sysBuilding.getCreateTime())
                        .orderByAsc("create_time").last("limit 1"));
                if (one==null){
                    continue;
                }
                List<SysGroupLog> list = sysGroupLogService.list (new QueryWrapper<SysGroupLog> ()
                        .eq ( "ordinal",one.getOrdinal ()).in("userid",ascUserids));

                int gt=0;
                if (list.size ()>0){
                    Optional<SysGroupLog> max = list.stream().max(Comparator.comparingInt(SysGroupLog::getGrade));
                    SysGroupLog sysGroupLog = max.get();
                    gt= sysGroupLog.getGrade();
                }
                if (gt>=grade){
                    grade=gt;
                }

                if (grade>=sysUserGroup.getGrade ()){
                    continue;
                }

                int gi=grade;
                List<SysGroupSetting> collect = settingList.stream().filter(sysGroupSetting ->
                        sysGroupSetting.getGrade().equals(gi)).collect(toList());
                int earnings1 = 0;
                if (collect!=null&&collect.size()>0){
                    earnings1 = collect.get ( 0 ).getEarnings ();
                    earnings=earnings-earnings1;
                }


                shouyi=one.getPrice()*one.getEarnings()*earnings/10000;
                /*long sum=0L;
                long sum1;
                long shouyi2;
                if (list.size ()>0){
                    sum= list.stream ().mapToLong ( SysGroupLog::getMoney ).sum ();
                }
                sum1=one.getPrice()*one.getEarnings()*sysSetting.getEarnings()/10000;
                long l = one.getPrice () * one.getEarnings () * earnings1 / 10000;
                shouyi2=sum1-(sum+l);

                if (shouyi2<=0){
                    continue;
                }

                if (shouyi>=shouyi2){
                    shouyi=shouyi2;
                }
                */

            }

            sysUserGroup.setMoney(sysUserGroup.getMoney()+shouyi);
            userMoney.setExpandMoney(userMoney.getExpandMoney()+shouyi);

            SysGroupLog sysGroupLog=new SysGroupLog();
            sysGroupLog.setType(one.getType());
            sysGroupLog.setGrade (sysUserGroup.getGrade());
            sysGroupLog.setOrdinal(one.getOrdinal());
            sysGroupLog.setUserid(userMoney.getUserid());
            sysGroupLog.setMoney(shouyi);
            sysGroupLog.setCreateTime(new Date());
            boolean save = sysGroupLogService.save ( sysGroupLog );
            if (!save){
                log.error ("日志保存错误！");
            }
        }

        Long shouyi=sysBuilding.getPrice()*sysBuilding.getEarnings()*sysSetting.getEarnings()/10000;
        SysGroupLog sysGroupLog=new SysGroupLog();
        sysGroupLog.setType(sysBuilding.getType());
        sysGroupLog.setOrdinal(sysBuilding.getOrdinal());
        sysGroupLog.setUserid(userMoney.getUserid());
        sysGroupLog.setGrade (sysUserGroup.getGrade());
        sysGroupLog.setMoney(shouyi);
        sysGroupLog.setCreateTime(new Date());
        boolean save = sysGroupLogService.save ( sysGroupLog );
        if (!save){
            log.error ("日志保存错误！");
        }

        sysUserGroup.setMoney(sysUserGroup.getMoney()+shouyi);
        userMoney.setExpandMoney(userMoney.getExpandMoney()+shouyi);
        long version = userMoney.getVersion();
        userMoney.setVersion(version+1);
        boolean update1 = userMoneyService.update ( userMoney, new QueryWrapper<UserMoney> ().eq ( "id", userMoney.getId () ).eq ( "version", version ) );
        if (!update1){
            log.error ("userMoney金额更新错误！");
        }
        int version1=sysUserGroup.getVersion();
        sysUserGroup.setVersion(version1+1);
        boolean update = sysUserGroupService.update ( sysUserGroup, new QueryWrapper<SysUserGroup> ().eq ( "id", sysUserGroup.getId () ).eq ( "version", version1 ) );
        if (!update){
            log.error ("sysUserGroup更新错误！");
        }
    }

    @Async
    @Transactional(rollbackFor = Exception.class,timeout = 360)
    public void group(String code){
        List<String> descId = sysUserGroupService.findDescId(code);
        if(descId == null || descId.size() == 0){
            return ;
        }
        List<SysUserGroup> sysUserGroups = sysUserGroupService.list(new QueryWrapper<SysUserGroup>().in("userid", descId));
        if(sysUserGroups == null || sysUserGroups.size() == 0){
            return ;
        }
        sysUserGroups.forEach(sysUserGroup -> {
            sysUserGroup.setGroupSize(sysUserGroup.getGroupSize()+1);
        });
        boolean b = sysUserGroupService.updateBatchById(sysUserGroups);
        if(!b){
            throw new UnsupportedOperationException("失败");
        }
    }
}
